import Random from "./random";
const CHARS = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
const CHARS2 = 'abcdefhijkmnprstwxyz';    /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/


/**
 * 工具类
 */
class Utils {
  
    numberFlag: boolean = false
    // 判断是否为空

    // 判断是否同一个星期
    isSameWeek = (time1, time2) => {
        let weekTime1 = this.getWeekTime(time1)
        let weekTime2 = this.getWeekTime(time2)
        if (weekTime1.weekDay == weekTime2.weekDay) {
            return true
        }
        return false
    }

    isSameDay = (time1, time2) => {
        let dayTime1 = new Date(time1).setHours(0, 0, 0, 0)
        let dayTime2 = new Date(time2).setHours(0, 0, 0, 0)
        if (dayTime1 == dayTime2) {
            return true
        }
        return false
    }
     simpleHashWithKey(text, key) {
        const combined = text + key;    
        let hash = 0;
        for (let i = 0; i < combined.length; i++) {
            const char = combined.charCodeAt(i);
            hash = (hash << 5) - hash + char; 
            hash |= 0; 
        }
        let result = hash.toString(16)
        result = result.slice(-8); 
        return result;
    }

     padStart(str, targetLength, padString) {
        // 转为字符串
        targetLength = targetLength >> 0; // 处理非数字的情况
        padString = String(padString || " ");
        
        if (str.length >= targetLength) {
            return String(this);
        } else {
            targetLength = targetLength - str.length;
            if (targetLength > padString.length) {
                padString += Array(Math.ceil(targetLength / padString.length)).join(padString);
            }
            return padString.slice(0, targetLength) + String(str);
        }
    };
    
    /**
    * 判断是否为空
    * @param value
    */
    isNull(value) {
        if (value === null || value == undefined) {
            return true
        }
        return false
    }
    isNotNull(value) {
        if (value !== null && value !== undefined) {
            return true
        }
        return false
    }

    /**
     * 获取随机字符串
     * @param len
     * @param rand
     */
    randomString(len, rand?: Random) {

        len = len || 32;
        var maxPos = CHARS.length;
        var pwd = '';
        for (var i = 0; i < len; i++) {
            if (rand) {
                pwd += CHARS.charAt(Math.floor(rand.floor(maxPos)));
            } else {
                pwd += CHARS.charAt(Math.floor(Math.random() * maxPos));
            }

        }
        return pwd;
    }
    randomRegisterString(len) {
        len = len || 32;
        var pwd = '';
        for (var i = 0; i < 4; i++) {
            pwd += CHARS2.charAt(Math.floor(Math.random() * CHARS2.length));
        }
        var char2s = '123456789';
        for (var i = 0; i < len; i++) {
            pwd += char2s.charAt(Math.floor(Math.random() * char2s.length));
        }
        return pwd;
    }
    randomRegisterPwd(len) {
        len = len || 8;
        var char2s = '123456789';
        var pwd = ""
        for (var i = 0; i < len; i++) {
            pwd += char2s.charAt(Math.floor(Math.random() * char2s.length));
        }
        return pwd;
    }
    /**
   * 获取数组中的一个元素
   * @param array
   * @param rand
   */
    getOneFromArray<T>(array: T[], rand?: Random): T {
        let newArray = array.slice(0)
        if (rand) {
            return newArray[Math.floor(rand.floor(array.length))]
        } else {
            return newArray[Math.floor(Math.random() * array.length)]
        }
    }
    getIndexByRandomArray(array: number[], rand: Random): number {
        let total = 0
        array.forEach((value, i) => {
            total += value
        })
        let r = rand.intn(total)
        let j = 0
        while (j < array.length) {
            if (r <= array[j]) {
                return j
            } else {
                r -= array[j]
            }
            j += 1
        }
        return j
    }


    floor = (value: number, len?: number) => {
        if (len == null) {
            len = 1
        }
        return Number(value.toFixed(len))
    }

    /**
     * 获取递增值
     * @param values
     * @param lvl
     */
    getIncValues(values: any[], lvl: number): number {
        let baseValue = values[0] || 0 //基础值
        let lvlValue = values[1] || 0  //等级系数
        let lvl10Value = values[2] || 0  //每10等级系数
        let lvl1ValueCoe = values[3] || 0 //每个等级的增长系数
        let lvl10ValueCoe = values[4] || 0 //每10个等级的增长系数
        let floorAmount = values[5] || 0 //保留的小数位数

        let v = baseValue + lvlValue * lvl + lvl10Value * Math.floor(lvl / 10) + lvl1ValueCoe * lvl * (lvl - 1) / 2 + lvl10ValueCoe * Math.floor(lvl / 10) * (Math.floor(lvl / 10) + 1) / 2

        if (floorAmount) {
            return utils.floor(v, floorAmount)
        } else {
            return Math.floor(v)
        }
    }

    /**
      * 获取随机数
      * @param min
      * @param max
      * @param rand
      */
    getRandomNumber(min: number, max: number, rand: Random): number {

        if (rand) {
            if (max < min) {
                return Math.floor(rand.floor(min - max + 1) + max)
            } else {
                return Math.floor(rand.floor(max - min + 1) + min)
            }
        } else {
            if (max < min) {
                return Math.floor(Math.random() * (min - max + 1) + max)
            } else {
                return Math.floor(Math.random() * (max - min + 1) + min)
            }
        }
    }
    /**
     * 获取随机数
     * @param min
     * @param max
     * @param rand
     */
    getRandomNumberFloor(min: number, max: number, rand: Random): number {
        if (rand) {
            if (max < min) {
                return rand.floor(min - max + 1) + max
            } else {
                return rand.floor(max - min + 1) + min
            }
        } else {
            if (max < min) {
                return Math.random() * (min - max + 1) + max
            } else {
                return Math.random() * (max - min + 1) + min
            }
        }
    }
    /**
     * 获取随机数组
     * @param array
     * @param num
     * @param rand
     */
    getRandomArrayNoRepeat<T>(array: T[], num: number, rand: Random): T[] {
        let arrayCopy = array.slice(0)
        let length = arrayCopy.length
        var k = []
        if (num > length) {
            num = length
        }
        for (var i = 0; i < num; i++) {
            var l = Math.floor(rand.floor(length))
            length = length - 1
            k.push(arrayCopy[l])
            arrayCopy[l] = arrayCopy[length]
        }
        return k
    }
    /**
     * 获取随机数组并移除
     * @param array
     * @param num
     * @param rand
     */
    getRandomArrayAndRemove<T>(array: T[], num: number, rand: Random): T[] {
        let arrayCopy = array
        let length = arrayCopy.length
        var k = []
        if (num > length) {
            num = length
        }
        for (var i = 0; i < num; i++) {
            var l = Math.floor(rand.floor(length))
            length = length - 1
            k.push(arrayCopy[l])
            arrayCopy[l] = arrayCopy[length]
            arrayCopy.pop()
        }
        return k
    }
    /** 获取数组中的一个元素并移除
     * @param array
     * @param rand
     */
    getOneFromArrayAndRemove<T>(array: T[], rand: Random): T {
        if (rand) {
            let index = Math.floor(rand.floor(array.length))
            let value = array[index]
            array.splice(index, 1)
            return value
        } else {
            let index = Math.floor(Math.random() * array.length)
            let value = array[index]
            array.splice(index, 1)
            return value
        }
    }
    addRandomByPer(value: number, per: number, maxPer: number, rand: Random, floor: number = 0): number {
        let max = value * maxPer * 100
        if (max <= 0) {
            max = 0
        }
        let min = value * per * 100
        if (min <= 0) {
            min = 0
        }
        let n = this.getRandomNumberFloor(min, max, rand) / 10000
        if (n > max) {
            n = max
        }
        n = utils.floor(n, floor)
        return n

    }
    getPerByAttri(name: string | number) {
        if (typeof name == "string" && (name.indexOf('Per') !== -1 || name.indexOf('Rate') !== -1)) {
            return '%'
        } else {
            return ''
        }
    }
    isPerByAttri(name: string) {
        if (typeof name == "string" && (name.indexOf('Per') !== -1 || name.indexOf('Rate') !== -1)) {
            return true
        } else {
            return false
        }
    }
    getNumberText = (value) => {
        if (this.numberFlag == false) {
            if (value > 10000 && value < 10000000) {
                return utils.floor(value / 10000, 1) + 'w'
            } else if (value >= 10000000 && value < 100000000) {
                return utils.floor(value / 10000, 1) + 'w'
            } else if (value >= 100000000) {
                return utils.floor(value / 100000000, 1) + 'y'
            }
        }
        return value
    }

    getWeekTime = (time) => {
        let weekDay = Math.floor((time - 1686412800000) / (7 * 24 * 60 * 60 * 1000))
        let weekTime = 1686412800000 + weekDay * (7 * 24 * 60 * 60 * 1000)
        let nextWeekDay = weekDay + 1
        let nextWeekTime = 1686412800000 + nextWeekDay * (7 * 24 * 60 * 60 * 1000)
        return { weekDay, weekTime, nextWeekDay, nextWeekTime }
    }
    /**
     * 二次方程求解
     * @param a
     * @param b
     * @param c
     */
    calculateQuadratic(a, b, c) {
        let discriminant = b * b - 4 * a * c;
        let firstSolution, secondSolution;

        if (discriminant > 0) {
            firstSolution = (-b + Math.sqrt(discriminant)) / (2 * a);
            return firstSolution;
        } else if (discriminant === 0) {
            firstSolution = secondSolution = (-b) / (2 * a);
            return firstSolution; // 如果只有一个解，返回数组只有一个元素
        } else {
            return null; // 无实数解
        }
    }
    // qualityOdds: [
    //     [10000, 4000, 1000, 300, 100, 30],
    //     [-100, -10, -5, 10, 5, 1],
    // ],
    getQualityByodds(lucky: number, minQuality: number, maxQuality: number, qualityOdds: any[], rand: Random) {
        let qualityOdd = qualityOdds[0].slice(0)
        let qualityCoe = qualityOdds[1].slice(0)
        let total = 0
        let oddValues = []
        qualityOdd.forEach((_, i) => {
            if (i <= maxQuality && i >= minQuality) {
                let value = qualityOdd[i] + qualityCoe[i] * lucky
                if (value <= 0) {
                    value = 0
                }
                total += value
                oddValues.push(value)
            }
        })

        let randValue = rand.intn(total)

        let i = minQuality
        while (i < oddValues.length && i <= maxQuality) {
            if (randValue <= oddValues[i - minQuality]) {
                break;
            } else {
                randValue -= oddValues[i - minQuality]
            }
            i++
        }

        if (i > maxQuality) {
            i = minQuality
        }
        return i
    }

    getItemsByRate(dataList: any[], amount: number, random: Random) {
        let totalHatred = 0
        let items = []
        let hartreds: any[] = []
        dataList.forEach(item => {
            totalHatred += item.rate
            hartreds.push({ value: item.rate, item })
        })
        for (let i = 0; i < amount && i < dataList.length; i++) {
            let randValue = random.intn(totalHatred)
            let j = 0
            while (j < hartreds.length) {
                if (randValue <= hartreds[j].value) {
                    totalHatred -= hartreds[j].value
                    hartreds[j].value = 0
                    items.push(hartreds[j].item)
                    break
                }
                randValue -= hartreds[j].value
                j += 1
            }
        }
        return items
    }

    keys(obj){
        var keys = [];
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                keys.push(key);
            }
        }
        return keys;
    }
    values(obj) {
        var values = [];
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                values.push(obj[key]);
            }
        }
        return values;
    }
    entries(obj) {
        var entries = [];
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                entries.push([key, obj[key]]);
            }
        }
        return entries;
    }
    assign(...data: any[]):any {
        
        var to = {}; // 将目标转换为对象
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];
            if (source !== null && source !== undefined) {
                for (var key in source) {
                    if (source.hasOwnProperty(key)) {
                        to[key] = source[key]; // 复制源对象的可枚举属性
                    }
                }
            }
        }
    
        return to; // 返回目标对象
    }
}

let utils = new Utils()
export default utils
